home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
fractal
/
frasr182
/
targa.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-18
|
20KB
|
776 lines
/** targa.c **/
#ifdef __TURBOC__
# pragma warn -par
#endif
#define TARGA_DATA
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef XFRACT
#include <conio.h>
#endif
#include "targa.h"
#include "fractint.h"
#include "prototyp.h"
/************* ****************/
extern char far *mapdacbox;
/************* ****************/
void WriteTGA( int x, int y, int index );
int ReadTGA ( int x, int y );
void EndTGA ( void );
void StartTGA( void );
void ReopenTGA( void );
/************* ****************/
static unsigned _fastcall near Row16Calculate(unsigned,unsigned);
static void _fastcall near PutPix16(int,int,int);
static unsigned _fastcall near GetPix16(int,int);
static unsigned _fastcall near Row32Calculate(unsigned,unsigned);
static void _fastcall near PutPix32(int,int,int);
static unsigned _fastcall near GetPix32(int,int);
static void _fastcall near DoFirstPixel(int,int,int);
static void _fastcall fatalerror(char far *);
static int GetLine(int);
static void _fastcall near SetDispReg(int,int);
static int VWait(void);
static void _fastcall SetVBorder(int,int);
static void _fastcall SetBorderColor(long);
static void _fastcall SetVertShift(int);
static void _fastcall SetInterlace(int);
static void _fastcall SetBlndReg(int);
static void _fastcall SetRGBorCV(int);
static void _fastcall SetVCRorCamera(int);
static void _fastcall SetMask(int);
static void _fastcall SetBlndReg(int);
static void _fastcall SetContrast(int);
static void _fastcall SetHue(int);
static void _fastcall SetSaturation(int);
static void _fastcall SetHBorder(int,int);
static void SetFixedRegisters(void);
static void _fastcall VCenterDisplay(int);
static void _fastcall SetOverscan(int);
static void _fastcall near TSetMode(int);
static int GraphInit(void);
static void GraphEnd(void);
/************* ****************/
int xorTARGA;
unsigned far *tga16 = NULL; /* [256] */
long far *tga32; /* [256] */
static int last = 0;
/************* ****************/
extern int sxdots,sydots; /* # of dots on the physical screen */
static int initialized;
/************* ****************/
static void (near _fastcall *DoPixel) ( int x, int y, int index );
static void (near _fastcall *PutPixel)( int x, int y, int index );
static unsigned (near _fastcall *GetPixel)( int x, int y );
/**************************************************************************/
#ifdef __BORLANDC__
#if(__BORLANDC__ > 2)
#pragma warn -eff
#endif
#endif
static unsigned _fastcall near Row16Calculate( unsigned line, unsigned x1 )
{
outp( DESTREG, (line >> 5) );
return( ((line & 31) << 10) | (x1 << 1) ); /* calc the pixel offset */
}
/**************************************************************************/
static void _fastcall near PutPix16( int x, int y, int index )
{
unsigned far * ip;
/**************/
ip = MK_FP( MEMSEG, Row16Calculate( y, x ) );
if( ! xorTARGA )
*ip = tga16[index];
else
*ip = *ip ^ 0x7fff;
}
/**************************************************************************/
static unsigned _fastcall near GetPix16( int x, int y )
{
register unsigned pixel, index;
unsigned far * ip;
/**************/
ip = MK_FP( MEMSEG, Row16Calculate( y, x ) );
pixel = *ip & 0x7FFF;
if( pixel == tga16[last] ) return( last );
for( index = 0; index < 256; index++ )
if( pixel == tga16[index] ) {
last = index;
return( index );
}
return( 0 );
}
/**************************************************************************/
static unsigned _fastcall near Row32Calculate( unsigned line, unsigned x1 )
{
outp( DESTREG, (line >> 4) );
return ( ((line & 15) << 11) | (x1 << 2) ); /* calc the pixel offset */
}
/**************************************************************************/
static void _fastcall near PutPix32( int x, int y, int index )
{
long far * lp;
lp = MK_FP( MEMSEG, Row32Calculate( y, x ) );
if( ! xorTARGA )
*lp = tga32[index];
else
*lp = *lp ^ 0x00FFFFFF;
}
/**************************************************************************/
static unsigned _fastcall near GetPix32( int x, int y )
{
register int index;
long pixel;
long far * lp;
lp = MK_FP( MEMSEG, Row32Calculate( y, x ) );
pixel = *lp & 0x00FFFFFF;
if( pixel == tga32[last] ) return( last );
for( index = 0; index < 256; index++ )
if( pixel == tga32[index] ) {
last = index;
return( index );
}
return( 0 );
}
/**************************************************************************/
static void _fastcall near DoFirstPixel( int x, int y, int index )
{
int cnt;
TSetMode( targa.mode | 1 );
for( cnt = 0; cnt < targa.MaxBanks; cnt += 2 ) { /* erase */
outp( DESTREG, cnt );
outp( SRCREG, cnt + 1 );
erasesegment(targa.memloc,0); /** general.asm **/
}
TSetMode( targa.mode & 0xFFFE );
PutPixel = DoPixel;
(*PutPixel)( x, y, index );
}
#ifdef __BORLANDC__
#if(__BORLANDC__ > 2)
#pragma warn +eff
#endif
#endif
/***************************************************************************/
void WriteTGA( int x, int y, int index )
{
OUTPORTB(MODEREG, targa.mode |= 1 ); /* TSetMode inline for speed */
(*PutPixel)( x, sydots-y, index&0xFF ); /* fix origin to match EGA/VGA */
OUTPORTB(MODEREG, targa.mode &= 0xFFFE );
}
/***************************************************************************/
int ReadTGA( int x, int y )
{
int val;
OUTPORTB(MODEREG, targa.mode |= 1 ); /* TSetMode inline for speed */
val = (*GetPixel)( x, sydots-y );
OUTPORTB(MODEREG, targa.mode &= 0xFFFE );
return( val );
}
/***************************************************************************/
void EndTGA( void )
{
if( initialized ) {
GraphEnd();
initialized = 0;
}
}
/***************************************************************************/
void StartTGA()
{
int i;
static char far couldntfind[]={"Could not find Targa card"};
static char far noenvvar[]={"TARGA environment variable missing"};
static char far insuffmem[]={"Insufficient memory for Targa"};
/****************/
if( initialized ) return;
initialized = 1;
/****************/
/* note that video.asm has already set the regualar video adapter */
/* to text mode (ax in Targa table entries is 3); */
/* that's necessary because TARGA can live at 0xA000, we DO NOT */
/* want to have an EGA/VGA in graphics mode!! */
ReopenTGA(); /* clear text screen and display message */
/****************/
/*** look for and activate card ***/
if ((i = GraphInit()))
fatalerror((i == -1) ? couldntfind : noenvvar);
VCenterDisplay( sydots + 1 );
if (tga16 == NULL)
if ( (tga16 = (unsigned far *)farmemalloc(512L)) == NULL
|| (tga32 = (long far *)farmemalloc(1024L)) == NULL)
fatalerror(insuffmem);
SetTgaColors();
if( targa.boardType == 16 ) {
GetPixel = GetPix16;
DoPixel = PutPix16;
}
else {
GetPixel = GetPix32;
DoPixel = PutPix32;
}
PutPixel = DoFirstPixel; /* on first pixel --> erase */
if( sydots == 482 ) SetOverscan( 1 );
TSetMode( targa.mode & 0xFFFE );
/****************/
if (mapdacbox == NULL && SetColorPaletteName("default") != 0)
exit( 1 ); /* stopmsg has already been issued */
}
void ReopenTGA()
{
static char far runningontarga[]={"Running On TrueVision TARGA Card"};
helptitle();
putstring(2,20,7,runningontarga);
movecursor(6,0); /* in case of brutal exit */
}
static void _fastcall fatalerror(char far *msg)
{
static char far abortmsg[]={"...aborting!"};
putstring(4,20,15,msg);
putstring(5,20,15,abortmsg);
movecursor(8,0);
exit(1);
}
/*** the rest of this module used to be separate, in tgasubs.c, ***/
/*** has now been merged into a single source ***/
/*******************************************************************/
static void _fastcall VCenterDisplay( int nLines )
{
int lines;
int top, bottom;
long color;
lines = nLines >> 1; /* half value of last line 0..x */
top = 140 - (lines >> 1);
bottom = top + lines;
SetVBorder( top, bottom );
SetVertShift( 255 - lines ); /* skip lines we're not using */
if( targa.boardType == 16 )
color = (12 << 10) | (12 << 5) | 12;
else
color = ((long)80 << 16) | (80 << 8) | 80;
SetBorderColor( color );
}
/*****************************************************************/
static void _fastcall near SetDispReg(int reg, int value)
{
targa.DisplayRegister[reg] = value;
TSetMode(targa.mode&MSK_REGWRITE); /* select Index Register write */
OUTPORTB(DRREG, reg); /* select sync register */
/*
* Set Mask register to write value to
* display register and to set Bit 9 in the DR
*/
TSetMode( ((targa.mode|(~MSK_REGWRITE)) /* turn on write bit */
& MSK_BIT9 ) /* turn off Bit 9 */
| ((value&0x0100)>>1)); /* set bit 9 for value */
OUTPORTB(DRREG, value); /* select sync register */
}
/*****************************************************************/
#define WAITCOUNT 60000
static int VWait()
{
int rasterreg;
unsigned GiveUp;
rasterreg = RASTERREG;
/*
* If beyond bottom of frame wait for next field
*/
GiveUp= WAITCOUNT;
while ( (--GiveUp) && (GetLine(rasterreg) == 0) ) { }
if (GiveUp) {
/*
* Wait for the bottom of the border
*/
GiveUp= WAITCOUNT;
while ( (--GiveUp) && (GetLine(rasterreg) > 0) ) { }
}
return ( ( GiveUp ) ? 0 : -1);
}
/*****************************************************************/
static void _fastcall SetVBorder(int top, int bottom)
{
/* top border */
if ( top < MIN_TOP ) top=MIN_TOP;
SetDispReg(TOPBORDER,top);
/* bottom border */
if ( bottom > MAX_BOTTOM ) bottom=MAX_BOTTOM;
SetDispReg(BOTTOMBORDER,bottom);
SetDispReg(DR10,top);
SetDispReg(DR11,bottom);
}
/*****************************************************************/
static void _fastcall SetRGBorCV(int type)
{
/* set the contrast level */
targa.RGBorCV = type;
targa.VCRCon = ( targa.VCRCon & MSK_RGBORCV ) |
(targa.RGBorCV<<SHF_RGBORCV) ;
OUTPORTB(VCRCON, targa.VCRCon );
}
/*****************************************************************/
static void _fastcall SetVCRorCamera(int type)
{
targa.VCRorCamera = type&1;
targa.VCRCon = ( targa.VCRCon & MSK_VCRORCAMERA ) |
(targa.VCRorCamera<<SHF_VCRORCAMERA) ;
OUTPORTB(VCRCON, targa.VCRCon );
}
/*****************************************************************/
static void _fastcall SetBorderColor(long color)
{
targa.BorderColor = color;
OUTPORTB(BORDER, (int)(0x0000ffffL&(color)));
OUTPORTB((BORDER+2), (int)((color)>>16));
}
/*****************************************************************/
static void _fastcall SetMask(int mask)
{
/* mask to valid values and output to mode register */
targa.Mask = mask;
OUTPORTB(MASKREG, mask);
}
/*****************************************************************/
static void _fastcall SetVertShift(int preshift)
{
/* set the Vertical Preshift count level */
targa.VertShift = preshift;
OUTPORTB(VERTPAN, preshift);
}
/*****************************************************************/
static void _fastcall SetOverscan(int mode)
{
long tempColor;
targa.ovrscnOn = mode;
if ( mode == 0 ) {
INPORTB(UNDERREG); /* select underscan mode */
SetHBorder( (DEF_LEFT+targa.xOffset),
(DEF_RIGHT+targa.xOffset));
SetDispReg(4,352);
SetDispReg(5,1);
SetBorderColor(targa.BorderColor);
}
else {
INPORTB(OVERREG); /* select overrscan mode */
SetDispReg(0,64); /* Set four of the display registers */
SetDispReg(1,363); /* to values required for Overscan */
SetDispReg(4,363);
SetDispReg(5,17);
tempColor = targa.BorderColor;
SetBorderColor(0L);
targa.BorderColor = tempColor;
}
}
/*****************************************************************/
static void _fastcall SetInterlace(int type)
{
targa.InterlaceMode= type & MSK_INTERLACE;
SetDispReg(INTREG, targa.InterlaceMode);
/*
* SET THE INTERLACE BIT TO MATCH THE INTERLACE MODE AND
* SCREEN RESOLUTION - SCREEN PAGE
*/
if ( ( targa.InterlaceMode >= 2 ) &&
( targa.PageMode> 1 ) &&
( (targa.PageMode&1) != 0 ) )
TSetMode(targa.mode|(~MSK_IBIT) );
else
TSetMode(targa.mode& MSK_IBIT);
}
/*****************************************************************/
static void _fastcall SetBlndReg(int value)
{
/* set the Vertical Preshift count level */
if ( targa.boardType == 32 ) {
targa.VCRCon = (targa.VCRCon&0xfe) | value;
OUTPORTB(BLNDREG, value);
}
}
/*****************************************************************/
static void _fastcall near TSetMode(int mode)
{
/* mask to valid values and output to mode register */
OUTPORTB(MODEREG, mode );
targa.mode = mode;
}
/*****************************************************************/
static void _fastcall SetContrast(int level)
{
/* set the contrast level */
targa.Contrast = level &((~MSK_CONTRAST)>>SHF_CONTRAST);
targa.VCRCon = ( targa.VCRCon & MSK_CONTRAST ) |
(targa.Contrast<<SHF_CONTRAST) ;
OUTPORTB(VCRCON, targa.VCRCon );
}
/*****************************************************************/
static void _fastcall SetHue(int level)
{
/* set the hue level - Mask to valid value */
targa.Hue = level&((~MSK_HUE)>>SHF_HUE);
/* mask to valid range */
targa.SatHue = (targa.SatHue&MSK_HUE) | (targa.Hue<<SHF_HUE);
OUTPORTB(SATHUE, targa.SatHue );
}
/*****************************************************************/
static void _fastcall SetSaturation(int level)
{
/* set the saturation level */
targa.Saturation= level&( (~MSK_SATURATION)>>SHF_SATURATION);
targa.SatHue = (targa.SatHue&MSK_SATURATION) |
(targa.Saturation<<SHF_SATURATION);
OUTPORTB(SATHUE , targa.SatHue );
}
/*************************************************************/
/*** UNUSED
static void _fastcall SetPageMode(int pageMode)
{
pageMode &= 0x07;
targa.PageMode = pageMode;
VWait();
TSetMode( (targa.mode)&(MSK_RES) |((pageMode<<SHF_RES)&(~MSK_RES)) ) ;
if ( ( targa.DisplayRegister[20] >= 2 ) &&
( pageMode> 1 ) &&
( (pageMode&1) != 0 ) ) TSetMode(targa.mode|(~MSK_IBIT) );
else
TSetMode(targa.mode& MSK_IBIT);
}
***/
/*****************************************************************/
static void _fastcall SetHBorder(int left, int right)
{
SetDispReg(LEFTBORDER, left); /* set horizontal left border */
SetDispReg(RIGHTBORDER,right); /* set horizontal right border */
/*
* Set DR 8 and 9 since they
* default to tracking DR0 and DR 1
*/
SetDispReg(DR8,left);
SetDispReg(DR9,left);
}
/*****************************************************************/
/*** UNUSED
static void _fastcall SetGenlock(int OnOrOff)
{
TSetMode( (targa.mode)&(MSK_GENLOCK)
|((OnOrOff<<SHF_GENLOCK)&(~MSK_GENLOCK)) );
}
***/
/*****************************************************************/
/* was asm, TC fast enough on AT */
static int GetLine( int port )
{
int cnt;
int val1, val2;
val1 = INPORTB( port );
for( cnt = 0; cnt < 20; cnt++ ) {
val2 = INPORTB( port );
if( val1 == val2 )
break;
val1 = val2;
}
return( val1 );
}
/**********************************************************************
TINIT
**********************************************************************/
static int GraphInit()
{
int i;
int bottom, top;
char *envptr;
unsigned switches, got_switches;
memset( &targa, 0, sizeof(targa) );
targa.boardType = TYPE_16; /* default to T16 */
targa.xOffset = 0; targa.yOffset = 0; /* default to no offset */
targa.LinesPerField= DEF_ROWS/2; /* number of lines per field */
targa.AlwaysGenLock = DEF_GENLOCK; /* default to genlock off */
targa.PageMode = 0;
targa.InterlaceMode = DEF_INT; /* Defalut: Interlace Mode 0 */
targa.Contrast= DEF_CONTRAST;
targa.Saturation = DEF_SATURATION;
targa.Hue = DEF_HUE;
targa.RGBorCV = CV; /* default to Composite video */
targa.VCRorCamera = CAMERA;
targa.PanXOrig = 0; targa.PanYOrig=0;
targa.PageUpper= 0xffff; /* set the bank flags to illega& values */
targa.PageLower= 0xffff; /* so that they will be set the first time */
targa.ovrscnAvail = 0; /* Assume no Overscan option */
targa.ovrscnOn = 0;
if ((envptr = getenv("TARGA")) == NULL)
return(-2);
switches = got_switches = 0;
while (*envptr) {
if (*envptr != ' ') ++got_switches;
if (*envptr >= '2' && *envptr <= '8')
switches |= (1 << ('8' - *envptr));
++envptr;
}
if (got_switches == 0) { /* all blanks, use default */
targa.memloc = (signed int)0xA000;
targa.iobase = 0x220;
}
else {
targa.memloc = 0x8000 + ((switches & 0x70) << 8);
targa.iobase = 0x200 + ((switches & 0x0f) << 4);
}
if ((envptr = getenv("TARGASET"))) {
while(1) { /* parse next parameter */
while (*envptr == ' ' || *envptr == ',') ++envptr;
if (*envptr == 0) break;
if (*envptr >= 'a' && *envptr <= 'z') *envptr -= ('a'-'A');
i = atoi(envptr+1);
switch (*envptr) {
case 'T':
if (i == 16) targa.boardType = TYPE_16;
if (i == 24) targa.boardType = TYPE_24;
if (i == 32) targa.boardType = TYPE_32;
break;
/* case 'E' not done, meaning not clear */
case 'X':
targa.xOffset = i;
break;
case 'Y':
targa.yOffset = i;
break;
case 'I':
targa.InterlaceMode = i;
break;
/* case 'N' not done, I don't know how to handle it */
case 'R':
targa.RGBorCV = RGB;
break;
case 'B':
targa.VCRorCamera = CAMERA;
break;
case 'V':
targa.VCRorCamera = VCR;
break;
case 'G':
targa.AlwaysGenLock = 1;
break;
case 'C':
targa.Contrast = i * 31 / 100;
break;
case 'S':
targa.Saturation = i * 7 / 100;
break;
case 'H':
targa.Hue = i * 31 / 100;
break;
/* note: 'A' and 'O' defined but apply only to type M8 */
/* case 'P' not handled cause I don't know how */
}
while (*(++envptr) >= '0' && *envptr <= '9') { }
}
}
if ( targa.boardType == TYPE_16 ) {
targa.MaxBanks = 16;
targa.BytesPerPixel = 2;
}
if ( targa.boardType == TYPE_24 ) {
targa.MaxBanks = 32;
targa.BytesPerPixel = 3;
}
if ( targa.boardType == TYPE_32 ) {
targa.MaxBanks = 32;
targa.BytesPerPixel = 4;
}
/****** Compute # of rows per 32K bank ********/
targa.RowsPerBank = 512/(targa.MaxBanks);
targa.AddressShift = targa.MaxBanks>>4;
/* if initializing CVA: set these before we quit */
SetSaturation(targa.Saturation);
SetHue(targa.Hue);
SetContrast( targa.Contrast);
/* Set Genlock bit if always genlocked */
/* Set before flipping and jerking screen */
TSetMode( (targa.AlwaysGenLock<<SHF_GENLOCK) | DEF_MODE);
SetBlndReg(0); /* disable blend mode on TARGA 32 */
SetInterlace(targa.InterlaceMode);
SetFixedRegisters();
SetOverscan( 0 );
top = 140 - (targa.LinesPerField / 2);
bottom = top + targa.LinesPerField;
SetVBorder(top,bottom);
SetVertShift(256-targa.LinesPerField);
SetMask(DEF_MASK);
SetRGBorCV (targa.RGBorCV );
SetVCRorCamera(targa.VCRorCamera);
/* See if the raster register is working correctly and
return error flag if its not */
return (( VWait() == -1) ? -1 : 0);
}
/**************************************************************/
static void GraphEnd()
{
TSetMode( (targa.mode)&MSK_MSEL ); /* disable memory */
}
/**************************************************************/
/* Set the registers which have required values */
#define FIXED_REGS 10
static int FixedRegs[] = {
DR6,DR7,DR12,DR13,DR14,DR15,DR16,DR17,DR18,DR19
};
static int FixedValue[] = {
DEF_DR6,DEF_DR7,DEF_DR12,DEF_DR13,DEF_DR14,
DEF_DR15,DEF_DR16,DEF_DR17,DEF_DR18,DEF_DR19
};
static void SetFixedRegisters()
{
int reg;
for ( reg=0; reg<FIXED_REGS; reg++)
SetDispReg(FixedRegs[reg],FixedValue[reg]);
}